class Person(id: String, name: String, age: Int) {
  val _id: String = id
  val _name: String = name
  val _age: Int = age

  def printName(): Unit = {
    println(s"这是Person类中的对象，名字为$name")
  }

  def walk(): Unit = {
    println("人类会行走")
  }

  override def toString: String = {
    return s"Person(${_id},${_name},${_age})"
  }
}

// Scala在继承父类时，需要调用父类的构造方法
class Teacher(id: String, name: String, age: Int, clazz: String) extends Person(id, name, age) {
  // 对子类特有的属性做初始化
  val _clazz: String = clazz

  // 父类中有同名的方法 需要加上override进行重写
  override def printName(): Unit = {
    println(s"这是Teacher类中的对象，名字为$name")
  }

  override def walk(): Unit = {
    println("老师也属于人类，也会行走")
  }

  def printClazz(): Unit = {
    println(this._clazz)
  }

  override def toString: String = {
    return s"Teacher(${_id},${_name},${_age},${_clazz})"
  }
}

// 继承能够获得父类定义好的属性及方法
class Student(id: String, name: String, age: Int, gender: String, clazz: String) extends Person(id, name, age) {
  val _gender: String = gender
  val _clazz: String = clazz

  override def printName(): Unit = {
    println(s"这是Student类中的对象，名字为$name")
  }

  def printGender(): Unit = {
    println(this._gender)
  }

  override def toString: String = {
    return s"Student(${_id},${_name},${_age},${_gender},${_clazz})"
  }

  override def walk(): Unit = {
    println("学生也属于人类，也会行走")
  }
}

object Demo04ScalaClassExtend {
  // 多态 父类引用指向子类对象
  def PersonWalkTwice(person: Person): Unit = {
    person.walk()
    person.walk()
  }

  def TeacherWalkTwice(person: Teacher): Unit = {
    person.walk()
    person.walk()
  }

  def StudentWalkTwice(person: Student): Unit = {
    person.walk()
    person.walk()
  }


  def main(args: Array[String]): Unit = {
    val p: Person = new Person("001", "p1", 20)
    println(p)
    println(p._id)
    p.walk()
    p.printName()

    val t: Teacher = new Teacher("002", "t1", 28, "文科班")
    println(t._name)

    val s: Student = new Student("003", "s1", 20, "男", "文科四班")
    println(s._name)
    println(s._gender)
    s.printGender()

    PersonWalkTwice(p)
    TeacherWalkTwice(t)
    StudentWalkTwice(s)

    PersonWalkTwice(t)
    PersonWalkTwice(s)

  }
}